from database_manager import db_manager
from datetime import datetime, timedelta
from collections import defaultdict
from display_formatter import DisplayFormatter


class AttendanceController:
    def __init__(self, view):
        self.view = view

    def on_attendance_clicked(self):
        """处理查看考勤按钮点击事件：显示详细的考勤统计报告"""
        if hasattr(self.view, 'reset_camera_and_controls'):
            self.view.reset_camera_and_controls()
        
        # 使用格式化工具创建标题
        header = DisplayFormatter.create_header("📋 考勤统计报告", 60)
        self.view.update_display(header)
        
        try:
            # 获取考勤记录
            records = db_manager.get_attendance_records(100)
            if not records:
                empty_messages = DisplayFormatter.create_empty_state_message('no_attendance')
                for msg in empty_messages:
                    self.view.update_display(msg)
                return
            
            # 显示总体统计
            self._display_overall_statistics(records)
            
            # 显示今日考勤情况
            self._display_today_attendance(records)
            
            # 显示个人考勤统计
            self._display_personal_statistics()
            
            # 显示最近考勤记录
            self._display_recent_records(records[:30])  # 显示最近30条
            
            # 显示完成信息
            completion_header = DisplayFormatter.create_header("✅ 考勤报告生成完成", 60, '=')
            self.view.update_display(completion_header)
            
        except Exception as e:
            self.view.update_display(f"❌ 查询考勤记录失败: {str(e)}")
    
    def _display_overall_statistics(self, records):
        """显示总体统计信息"""
        total_records = len(records)
        clock_in_count = sum(1 for _, action, _ in records if action == 'in')
        clock_out_count = sum(1 for _, action, _ in records if action == 'out')
        
        # 统计参与考勤的人数
        unique_people = set(name for name, _, _ in records)
        people_count = len(unique_people)
        
        # 使用格式化工具显示统计摘要
        summary_lines = DisplayFormatter.format_attendance_summary(
            total_records, people_count, clock_in_count, clock_out_count
        )
        for line in summary_lines:
            self.view.update_display(line)
        self.view.update_display("")
    
    def _display_today_attendance(self, records):
        """显示今日考勤情况"""
        today = datetime.now().date()
        today_records = []
        
        for name, action, ts in records:
            try:
                record_date = datetime.strptime(ts, '%Y-%m-%d %H:%M:%S').date()
                if record_date == today:
                    today_records.append((name, action, ts))
            except ValueError:
                continue
        
        # 按人员分组今日考勤
        today_by_person = defaultdict(list)
        for name, action, ts in today_records:
            today_by_person[name].append((action, ts))
        
        # 使用格式化工具显示今日考勤
        attendance_lines = DisplayFormatter.format_today_attendance(today_by_person)
        for line in attendance_lines:
            self.view.update_display(line)
        self.view.update_display("")
    
    def _display_personal_statistics(self):
        """显示个人考勤统计（最近30天）"""
        try:
            stats = db_manager.get_attendance_statistics(30)
            if not stats:
                return
            
            self.view.update_display("👥 个人考勤统计 (最近30天):")
            self.view.update_display("-" * 50)
            
            for name, clock_in_count, clock_out_count, last_attendance in stats:
                # 计算最后考勤时间
                try:
                    last_time = datetime.strptime(last_attendance, '%Y-%m-%d %H:%M:%S')
                    days_ago = (datetime.now() - last_time).days
                    if days_ago == 0:
                        time_desc = "今天"
                    elif days_ago == 1:
                        time_desc = "昨天"
                    else:
                        time_desc = f"{days_ago}天前"
                except ValueError:
                    time_desc = "未知"
                
                # 计算出勤率（假设每天需要上下班各一次）
                total_expected = min(clock_in_count, clock_out_count) * 2
                actual_records = clock_in_count + clock_out_count
                
                self.view.update_display(f"  📋 {name}:")
                self.view.update_display(f"    • 上班打卡: {clock_in_count} 次")
                self.view.update_display(f"    • 下班打卡: {clock_out_count} 次")
                self.view.update_display(f"    • 最后考勤: {last_attendance} ({time_desc})")
                
                # 显示考勤状态
                if clock_in_count > clock_out_count:
                    self.view.update_display(f"    • 状态: 🔴 可能未下班 (上班{clock_in_count - clock_out_count}次未匹配)")
                elif clock_out_count > clock_in_count:
                    self.view.update_display(f"    • 状态: ⚠️ 异常 (下班{clock_out_count - clock_in_count}次未匹配上班)")
                else:
                    self.view.update_display(f"    • 状态: ✅ 正常")
                
                self.view.update_display("")
            
        except Exception as e:
            self.view.update_display(f"  ❌ 个人统计获取失败: {str(e)}")
    
    def _display_recent_records(self, records):
        """显示最近的考勤记录"""
        section_header = DisplayFormatter.create_section_header("🕒 最近考勤记录")
        self.view.update_display(section_header)
        
        for i, (name, action, ts) in enumerate(records, 1):
            # 计算时间差
            try:
                record_time = datetime.strptime(ts, '%Y-%m-%d %H:%M:%S')
                time_ago = DisplayFormatter.format_time_ago(record_time)
            except ValueError:
                time_ago = ""
            
            # 使用格式化工具显示考勤记录
            record_line = DisplayFormatter.format_attendance_record(i, name, action, ts, time_ago)
            self.view.update_display(record_line)
        
        self.view.update_display("")

    def _insert_attendance(self, employee_name: str, action: str):
        try:
            db_manager.insert_attendance(employee_name, action)
        except Exception as e:
            self.view.update_display(f"考勤记录插入失败: {str(e)}")
            raise

    def _get_current_employee_name(self) -> str:
        # 优先使用识别到的姓名（若后续接入识别则设置 view.recognized_name）
        if hasattr(self.view, 'recognized_name') and self.view.recognized_name:
            return self.view.recognized_name
        # 回退到输入框姓名
        if hasattr(self.view, 'name_input'):
            text = self.view.name_input.text().strip()
            if text:
                return text
        return ''

    def on_clock_in_clicked(self):
        # 打卡前不重置，保持摄像头工作
        employee_name = self._get_current_employee_name()
        if not employee_name:
            self.view.update_display("未获取到姓名，请先识别或输入姓名。")
            return
        self._insert_attendance(employee_name, 'in')
        self.view.update_display(f"{employee_name} 上班打卡成功。")

    def on_clock_out_clicked(self):
        # 打卡前不重置，保持摄像头工作
        employee_name = self._get_current_employee_name()
        if not employee_name:
            self.view.update_display("未获取到姓名，请先识别或输入姓名。")
            return
        self._insert_attendance(employee_name, 'out')
        self.view.update_display(f"{employee_name} 下班打卡成功。")

    def get_today_attendance_data(self):
        """获取今日考勤数据，用于导出功能"""
        try:
            today = datetime.now().date()
            records = db_manager.get_attendance_records(1000)  # 获取足够多的记录
            
            # 筛选今日记录
            today_records = []
            for name, action, ts in records:
                try:
                    record_date = datetime.strptime(ts, '%Y-%m-%d %H:%M:%S').date()
                    if record_date == today:
                        today_records.append((name, action, ts))
                except ValueError:
                    continue
            
            # 按人员分组并计算工作时长
            attendance_data = []
            people_records = defaultdict(list)
            
            # 按人员分组
            for name, action, ts in today_records:
                people_records[name].append((action, ts))
            
            # 处理每个人的考勤数据
            for name, records_list in people_records.items():
                # 按时间排序
                records_list.sort(key=lambda x: x[1])
                
                clock_in_time = ""
                clock_out_time = ""
                work_duration = ""
                status = "正常"
                
                # 查找上班和下班时间
                for action, ts in records_list:
                    if action == 'in' and not clock_in_time:
                        clock_in_time = datetime.strptime(ts, '%Y-%m-%d %H:%M:%S').strftime('%H:%M:%S')
                    elif action == 'out':
                        clock_out_time = datetime.strptime(ts, '%Y-%m-%d %H:%M:%S').strftime('%H:%M:%S')
                
                # 计算工作时长
                if clock_in_time and clock_out_time:
                    try:
                        in_time = datetime.strptime(f"{today} {clock_in_time}", '%Y-%m-%d %H:%M:%S')
                        out_time = datetime.strptime(f"{today} {clock_out_time}", '%Y-%m-%d %H:%M:%S')
                        duration = out_time - in_time
                        hours = duration.total_seconds() / 3600
                        work_duration = f"{hours:.1f}小时"
                    except:
                        work_duration = "计算失败"
                elif clock_in_time and not clock_out_time:
                    status = "未下班"
                    work_duration = "进行中"
                elif not clock_in_time and clock_out_time:
                    status = "异常"
                    work_duration = "无上班记录"
                else:
                    status = "无记录"
                    work_duration = "0小时"
                
                attendance_data.append({
                    'name': name,
                    'date': today.strftime('%Y-%m-%d'),
                    'clock_in_time': clock_in_time or "未打卡",
                    'clock_out_time': clock_out_time or "未打卡",
                    'work_duration': work_duration,
                    'status': status
                })
            
            return attendance_data
            
        except Exception as e:
            print(f"获取今日考勤数据失败: {str(e)}")
            return []